
 export default function flexArgs(patterns,args,defaultValues={}){
    if(!Array.isArray(patterns) || (Array.isArray(patterns) && patterns.length===0)){
        throw new Error('Parameters pattern is required')
    }else if(args.length===1 && args[0].constructor === Object && patterns.filter(p=>Object.keys(p).length===1).some(p=>Object.values(p)[0]==="any")){
        //如果只一个参数,并且是一个{}，并且定义了一个{<x>:"any"}的，
        return {[Object.keys(patterns.filter(p=>Object.keys(p).length===1)[0])[0]]:args[0]}
    }else if(args.length===1 && args[0].constructor === Object && !patterns.filter(p=>Object.keys(p).length===1).some(p=>Object.values(p)[0]===Object)){
        //如果只一个参数,并且是一个{}，并且没有定义{<>:Object}的，则直接返回整个对象
        return Object.assign({},defaultValues,args[0])
    }else{
        let values =Object.assign({},defaultValues)
        // 过滤出参数定义里面参数个数与args相同的项
        // 比如args只有两个参数，则只需要过滤出patterns里面两项参数的pattern进行解析
        let argPatterns=patterns.filter((v)=>Object.keys(v).length===args.length)
        // 如果参数个数相同，则进行参数类型的比较
        for(let i=0;i<argPatterns.length;i++){
            let pattern = argPatterns[i];
            let index = 0;      // 位置参数索引
            let isMached=true
            values =Object.assign({},defaultValues)
            for(let [argName,argType] of Object.entries(pattern)){
                // 如果参数没有类型或类型相符
                try{
                    isMached = argType==undefined
                        || argType===null
                        || argType==='any'
                        || argType===args[index].constructor
                        || (typeof(argType)==="string" && typeof(argType.constructor) === typeof(args[index].constructor))
                        || (typeof(argType) === "function" && argType===args[index].constructor)
                }catch {
                    isMached = false
                }

                if(isMached){
                    if(argName in values && values[argName].constructor === Object ){
                        values[argName]=Object.assign(values[argName],args[index])
                    }else{
                        values[argName]=args[index]
                    }
                }else{      // 如果有一项不相符，则说明当前模式不匹配，因此进行下一个模式的匹配
                    break
                }
                index+=1
            }
            if(isMached) break
        }
        return values
    }
 }

